package aufgabe2;

import static org.junit.Assert.*;


import org.junit.Before;
import org.junit.Test;

public class MatrixTest {

	static ImplementationMathMatrix type1Array;
	static ImplementationMathMatrix type2ArrayList;
	static ImplementationMathMatrix type3list;
	static ImplementationMathMatrix pType1;
	static ImplementationMathMatrix pType2;
	static ImplementationMathMatrix array1;
	static ImplementationMathMatrix array2;
	static ImplementationMathMatrix arrayList1;
	static ImplementationMathMatrix arrayList2;
	static ImplementationMathMatrix list1;
	static ImplementationMathMatrix list2;
	
	@Before
	@Test
	public void testIn() {
		int size = 4;
		type1Array = aufgabe2.Matrix.getMatrixOfArray(0, 0);
		type2ArrayList = aufgabe2.Matrix.getMatrixOfArrayList(0, 0);
		type3list = aufgabe2.Matrix.getMatrixOfList(0, 0);
		pType1 = aufgabe2.MatrixGenerator.genRandMatrix(type1Array, size, 1.0, 10.0);
		pType2 = aufgabe2.MatrixGenerator.genRandMatrix(type1Array, size, 1.0, 10.0);
		array1 = aufgabe2.MatrixGenerator.dupMatrixToType(type1Array, pType1);
		array2 = aufgabe2.MatrixGenerator.dupMatrixToType(type1Array, pType2);
		arrayList1 = aufgabe2.MatrixGenerator.dupMatrixToType(type2ArrayList, pType1);;
		arrayList2 = aufgabe2.MatrixGenerator.dupMatrixToType(type2ArrayList, pType2);;
		list1 = aufgabe2.MatrixGenerator.dupMatrixToType(type3list, pType1);;
		list2 = aufgabe2.MatrixGenerator.dupMatrixToType(type3list, pType2);;
	}
	
	//Test der Addition
	@Test
	public void testAdd() {
		ImplementationMathMatrix arrayTest1 = pType1.addiere(pType2);
		ImplementationMathMatrix arrayTest2 = pType2.addiere(pType1);
		assertTrue(arrayTest1.equals(arrayTest2));
		assertTrue(arrayTest1.equalsSomehow(arrayTest2, 0.0001));
	}
	
	//Test der Multiplikation
	@Test
	public void testMul() {
		ImplementationMathMatrix arrayTest1 = (pType1.mul(pType2)).mul(pType1);
		ImplementationMathMatrix arrayTest2 = pType1.mul((pType2).mul(pType1));
		assertTrue(arrayTest1.equalsSomehow(arrayTest2, 0.0001));
	}
	
	//Test der Potenzierung
	@Test
	public void testPot() {
		ImplementationMathMatrix arrayTest1 = pType1.pot(2);
		ImplementationMathMatrix arrayTest2 = pType1.mul(pType1);
		assertTrue(arrayTest1.equals(arrayTest2));
		assertTrue(arrayTest1.equalsSomehow(arrayTest2, 0.0001));
	}
	
	//Test der Skalarmultiplikation
	@Test
	public void testSkarMul() {
		ImplementationMathMatrix arrayTest1 = pType1.skarMul(1);
		assertTrue(arrayTest1.equals(pType1));
		assertTrue(arrayTest1.equalsSomehow(pType1, 0.0001));
	}
	
	//Test auf Gleicheit der Addition zwischen den Implementationen
	@Test
	public void testAddAll() {
		ImplementationMathMatrix arrayTest1 = array1.addiere(array2);
		ImplementationMathMatrix arrayTest2 = arrayList1.addiere(arrayList2);
		ImplementationMathMatrix arrayTest3 = list1.addiere(list2);
		assertTrue(arrayTest1.equalsSomehow(arrayTest2, 0.0001));
		assertTrue(arrayTest2.equalsSomehow(arrayTest3, 0.0001));
		assertTrue(arrayTest3.equalsSomehow(arrayTest1, 0.0001));
	}
	
	//Test auf Gleicheit der Multiplikation zwischen den Implementationen
	@Test
	public void testMulAll() {
		ImplementationMathMatrix arrayTest1 = array1.mul(array2);
		ImplementationMathMatrix arrayTest2 = arrayList1.mul(arrayList2);
		ImplementationMathMatrix arrayTest3 = list1.mul(list2);
		assertTrue(arrayTest1.equalsSomehow(arrayTest2, 0.0001));
		assertTrue(arrayTest2.equalsSomehow(arrayTest3, 0.0001));
		assertTrue(arrayTest3.equalsSomehow(arrayTest1, 0.0001));
	}
	
	//Test auf Gleicheit der Potenzierung zwischen den Implementationen
	@Test
	public void testPotAll() {
		ImplementationMathMatrix arrayTest1 = array1.pot(2);
		ImplementationMathMatrix arrayTest2 = arrayList1.pot(2);
		ImplementationMathMatrix arrayTest3 = list1.pot(2);
		assertTrue(arrayTest1.equalsSomehow(arrayTest2, 0.0001));
		assertTrue(arrayTest2.equalsSomehow(arrayTest3, 0.0001));
		assertTrue(arrayTest3.equalsSomehow(arrayTest1, 0.0001));
	}
	
	//Test auf Gleicheit der Potenzierung zwischen den Implementationen
	@Test
	public void testPotAll2() {
		ImplementationMathMatrix arrayTest1 = array1.pot2(2);
		ImplementationMathMatrix arrayTest2 = arrayList1.pot2(2);
		ImplementationMathMatrix arrayTest3 = list1.pot2(2);
		assertTrue(arrayTest1.equalsSomehow(arrayTest2, 0.0001));
		assertTrue(arrayTest2.equalsSomehow(arrayTest3, 0.0001));
		assertTrue(arrayTest3.equalsSomehow(arrayTest1, 0.0001));
	}
	
	//Test auf Gleicheit der Skalarmultiplikation zwischen den Implementationen
	@Test
	public void testSkarAll() {
		ImplementationMathMatrix arrayTest1 = array1.skarMul(3);
		ImplementationMathMatrix arrayTest2 = arrayList1.skarMul(3);
		ImplementationMathMatrix arrayTest3 = list1.skarMul(3);
		// TODU Fluktuationen?
		assertTrue(arrayTest1.equals(arrayTest2));
		assertTrue(arrayTest2.equals(arrayTest3));
		assertTrue(arrayTest3.equals(arrayTest1));
		//assertTrue(arrayTest1.equalsSomehow(arrayTest2, 50.6000));
		//assertTrue(arrayTest2.equalsSomehow(arrayTest3, 50.000));
		//assertTrue(arrayTest3.equalsSomehow(arrayTest1, 50.0000));
	}
	
	//Test auf Gleicheit bei der Addition mit Mischung der Implementationen
	@Test
	public void testAddAllC() {
		ImplementationMathMatrix arrayTest1 = array1.addiere(list1);
		ImplementationMathMatrix arrayTest2 = arrayList1.addiere(array1);
		ImplementationMathMatrix arrayTest3 = list1.addiere(arrayList1);
		assertTrue(arrayTest1.equalsSomehow(arrayTest2, 0.0001));
		assertTrue(arrayTest1.equalsSomehow(arrayTest2, 0.0001));
		assertTrue(arrayTest2.equalsSomehow(arrayTest3, 0.0001));
		assertTrue(arrayTest3.equalsSomehow(arrayTest1, 0.0001));
	}
	
	//Test auf Gleicheit bei der Multiplikation mit Mischung der Implementationen
	@Test
	public void testMulAllC() {
		ImplementationMathMatrix arrayTest1 = array1.mul(list1);
		ImplementationMathMatrix arrayTest2 = arrayList1.mul(array1);
		ImplementationMathMatrix arrayTest3 = list1.mul(arrayList1);
		assertTrue(arrayTest1.equalsSomehow(arrayTest2, 0.0001));
		assertTrue(arrayTest2.equalsSomehow(arrayTest3, 0.0001));
		assertTrue(arrayTest3.equalsSomehow(arrayTest1, 0.0001));
	}

}
